package service

import (
	"strconv"
	"time"

	"gitee.com/sansaniot/ssiot-core/facade/env"
	"github.com/xuri/excelize/v2"

	"ssalarm/common/constant"
	"ssalarm/common/utils"
	"ssalarm/internal/alarm/models"
)

func GenRedisWarn(redisWarn *[]map[string]interface{}, postWarning []map[string]interface{}) {
	for _, v := range postWarning {
		obj := make(map[string]interface{})
		obj["name"], _ = v["name"]
		obj["warning_mode"] = v["warningMode"]
		obj["warning_type"] = v["warningType"]
		obj["warning_ulimit"] = v["warningUlimit"]
		obj["warning_dlimit"] = v["warningDlimit"]
		obj["warning_level"] = v["warningLevel"]
		obj["warning_save"] = v["warningSave"]
		obj["alarmType"] = v["alarmType"]
		obj["isError"] = v["isError"]
		obj["warning_elimit"] = v["warningElimit"]
		obj["triggerType"] = v["triggerType"]
		if v, ok := v["autoDone"]; ok {
			obj["autoDone"] = v.(bool)
		} else {
			obj["autoDone"] = false
		}
		obj["uploadPeriod"] = v["uploadPeriod"]
		obj["collectPeriod"] = v["collectPeriod"]
		//告警愿意和建议
		obj["alarmReason"] = v["alarmReason"]
		obj["suggestion"] = v["suggestion"]
		*redisWarn = append(*redisWarn, obj)
	}
}

var (
	AlarmHeaderName = []string{"告警类型", "告警设备", "告警变量", "告警值", "告警时间", "告警级别", "故障原因"}
	AlarmHeaderKey  = []string{"alarmType", "devName", "varName", "varValue", "alarmTime", "level", "reason"}
)

// 导出告警内容填充
func FillExportAlarmList(f *excelize.File, alarmList []models.SysAlarm, isRealAlarm bool) error {
	headerName := make([]string, len(AlarmHeaderName))
	headerKey := make([]string, len(AlarmHeaderKey))
	copy(headerName, AlarmHeaderName)
	copy(headerKey, AlarmHeaderKey)
	if !isRealAlarm {
		headerName = utils.InsertIntoSlice(headerName, 5, "更新时间")
		headerKey = utils.InsertIntoSlice(headerKey, 5, "updateTime")
	}
	// 头部单元格样式
	headerCellStyle, _ := f.NewStyle(&excelize.Style{
		Font: &excelize.Font{
			Bold: true,
		},
		Alignment: &excelize.Alignment{
			Horizontal: "center",
			Vertical:   "center",
		},
		Border: []excelize.Border{
			{Type: "left", Color: "000000", Style: 1},
			{Type: "top", Color: "000000", Style: 1},
			{Type: "bottom", Color: "000000", Style: 1},
			{Type: "right", Color: "000000", Style: 1},
		},
	})
	sheetName := "告警信息"
	_ = f.NewSheet(sheetName)
	// 第1行
	_ = f.InsertRow(sheetName, 1)
	colNum := len(headerName)
	for n := 0; n < colNum; n++ {
		axis, _ := excelize.ColumnNumberToName(n + 1)
		_ = f.SetCellValue(sheetName, axis+"1", headerName[n])
		_ = f.SetCellStyle(sheetName, axis+"1", axis+"1", headerCellStyle)
		_ = f.SetColWidth(sheetName, axis, axis, 20)
	}
	snNameMapper := devname()
	levels := []string{"一般告警", "重要告警", "严重告警", "危险告警"}
	// 数据行起始
	startRow := 2
	size := len(headerKey)
	// 填充已有数据模型
	varSize := len(alarmList)
	for row := startRow; row-startRow < varSize; row++ {
		_ = f.InsertRow(sheetName, row)
		devVariable := alarmList[row-startRow]
		rowStr := strconv.Itoa(row)
		for colIndex := 0; colIndex < size; colIndex++ {
			key := headerKey[colIndex]
			axis, _ := excelize.ColumnNumberToName(colIndex + 1)
			switch key {
			case "alarmType":
				_ = f.SetColWidth(sheetName, axis, axis, 30)
				_ = f.SetCellValue(sheetName, axis+rowStr, devVariable.AlarmType)
				break
			case "devName":
				if devName, ok := snNameMapper[devVariable.DevSn]; ok {
					_ = f.SetCellValue(sheetName, axis+rowStr, devName)
				} else {
					_ = f.SetCellValue(sheetName, axis+rowStr, devVariable.DevSn)
				}
				break
			case "varName":
				_ = f.SetCellValue(sheetName, axis+rowStr, utils.If(len(devVariable.VarName) == 0, devVariable.VarKey, devVariable.VarName).(string))
				break
			case "varValue":
				_ = f.SetColWidth(sheetName, axis, axis, 15)
				_ = f.SetCellValue(sheetName, axis+rowStr, devVariable.VarValue)
				break
			case "alarmTime":
				_ = f.SetColWidth(sheetName, axis, axis, 25)
				_ = f.SetCellValue(sheetName, axis+rowStr, utils.FormatTimeToStr(time.Time(*devVariable.AlarmTime)))
				break
			case "updateTime":
				_ = f.SetColWidth(sheetName, axis, axis, 25)
				if devVariable.UpdateTime != nil {
					_ = f.SetCellValue(sheetName, axis+rowStr, utils.FormatTimeToStr(time.Time(*devVariable.UpdateTime)))
				}
				break
			case "level":
				if devVariable.Level <= 0 || devVariable.Level > 4 {
					_ = f.SetCellValue(sheetName, axis+rowStr, strconv.Itoa(devVariable.Level))
					break
				}
				_ = f.SetCellValue(sheetName, axis+rowStr, levels[devVariable.Level-1])
				break
			case "reason":
				_ = f.SetColWidth(sheetName, axis, axis, 30)
				_ = f.SetCellValue(sheetName, axis+rowStr, devVariable.Reason)
				break
			default:
				break
			}
		}
	}
	return nil
}

func devname() map[string]string {
	m := make(map[string]string)
	devcache, _ := env.Cache.HashGetAll(constant.DeviceEasyCache)
	for sn, v := range devcache {
		info := utils.BytesToMap([]byte(v))
		name := utils.If(info["name"] != nil, info["name"], "").(string)
		m[sn] = name
	}
	return m
}
